﻿using System;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.Serialization.Formatters.Binary;
using System.Globalization;
using System.Threading;

namespace BetsBetsBets
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            #region Остаток от деления
            //ConsoleKeyInfo key;
            //do
            //{
            //    Console.Write("a = "); int a = Convert.ToInt32(Console.ReadLine()); Console.WriteLine();
            //    Console.Write("b = "); int b = Convert.ToInt32(Console.ReadLine()); Console.WriteLine();
            //    Console.Write("{0} mod {1} = {2}", a, b, a % b);
            //    key = Console.ReadKey();
            //   Console.WriteLine();
            //} while (key.Key!= ConsoleKey.Escape);
            //do
            //{
            //    Console.Write("a = "); double a = Convert.ToDouble(Console.ReadLine()); Console.WriteLine();
            //    Console.Write("Int {0}", (int)a);
            //    key = Console.ReadKey();
            //    Console.WriteLine();
            //} while (key.Key != ConsoleKey.Escape); 
            #endregion

            #region Аналитика

            //string report = "";
            //string[] data = File.ReadAllLines("path.txt");
            //StreamWriter reswriter = new StreamWriter("results.txt",false);

            //ArrayList minwin = new ArrayList();
            //ArrayList winwin = new ArrayList();
            //ArrayList timewin = new ArrayList();

            //report += "Min\tMid\tMax";
            //reswriter.WriteLine(report);
            //for (int i = 1; i < data.Length; i++)
            //{
            //    double[] row = Array.ConvertAll<string, double>(data[i].Split(new string[] { "\t" }, StringSplitOptions.RemoveEmptyEntries).Take<string>(4).ToArray<string>(), new Converter<string, double>(Double.Parse));
            //    report = String.Empty;


            //    #region Total MidWin
            //    //if ((row.Take(3).Min() != row[3]) && (row.Take(3).Max() != row[3]))
            //    //{
            //    //    double[] subrow = row.Where(s => s != row.Take(3).Max() && s != row.Take(3).Min()).ToArray();
            //    //    double mid = (subrow.Length != 0) ? subrow[0] : row.Take(3).Min();
            //    //    report += row.Take(3).Min() + "\t" + mid + "\t" + row.Take(3).Max() + "\t";
            //    //}
            //    #endregion
            //    #region  Total MinWin Delta
            //    //if (row.Take(3).Min() == row[3])
            //    //{
            //    //    double[] subrow = row.Where(s => s != row.Take(3).Max() && s != row.Take(3).Min()).ToArray();
            //    //    double mid = (subrow.Length != 0) ? subrow[0] : row.Take(3).Min();
            //    //    report += (-row.Take(3).Min() + row.Take(3).Max()).ToString();
            //    //}
            //    #endregion
            //    #region MinWin Delta~2
            //    //if (row.Take(3).Min() != row[3] && (row.Take(3).Max() - row.Take(3).Min()) >= 0.75d && (row.Take(3).Max() - row.Take(3).Min()) <= 1.35d)
            //    //{
            //    //    double[] subrow = row.Where(s => s != row.Take(3).Max() && s != row.Take(3).Min()).ToArray();
            //    //    double mid = (subrow.Length != 0) ? subrow[0] : row.Take(3).Min();
            //    //    report += row.Take(3).Min() + "\t" + mid + "\t" + row.Take(3).Max();
            //    //} 
            //    #endregion

            //    #region WinRate + Condition 1
            //    //if ((row.Take(3).Min() != row[3]) && (row.Take(3).Max() != row[3]))
            //    //{
            //    //    double[] subrow = row.Where(s => s != row.Take(3).Max() && s != row.Take(3).Min()).ToArray();
            //    //    double mid = (subrow.Length != 0) ? subrow[0] : row.Take(3).Min();
            //    //    minwin.Add((row.Take(3).Min() + "\t" + mid + "\t" + row.Take(3).Max()).ToString());
            //    //}
            //    //else
            //    //{
            //    //    double[] subrow = row.Where(s => s != row.Take(3).Max() && s != row.Take(3).Min()).ToArray();
            //    //    double mid = (subrow.Length != 0) ? subrow[0] : row.Take(3).Min();
            //    //    winwin.Add((row.Take(3).Min() + "\t" + mid + "\t" + row.Take(3).Max()).ToString());
            //    //}
            //    #endregion
            //    #region WinRate + Condition 2
            //    //if (row.Take(3).Min() >= 2.35d && row.Take(3).Min() <= 2.55 && row.Take(3).Max() >= 3.35d && row.Take(3).Max() <= 3.55d)
            //    //{
            //    //    double[] subrow = row.Where(s => s != row.Take(3).Max() && s != row.Take(3).Min()).ToArray();
            //    //    double mid = (subrow.Length != 0) ? subrow[0] : row.Take(3).Min();
            //    //    if (row.Take(3).Min() == row[3]) minwin.Add((row.Take(3).Min() + "\t" + mid + "\t" + row.Take(3).Max()).ToString());
            //    //    else winwin.Add((row.Take(3).Min() + "\t" + mid + "\t" + row.Take(3).Max()).ToString());
            //    //    timewin.Add(1);
            //    //    report += row.Take(3).Min() + "\t" + mid + "\t" + row.Take(3).Max() + "\t" + 1 + "\t";
            //    //}
            //    //else
            //    //{
            //    //    double[] subrow = row.Where(s => s != row.Take(3).Max() && s != row.Take(3).Min()).ToArray();
            //    //    double mid = (subrow.Length != 0) ? subrow[0] : row.Take(3).Min();
            //    //    report += row.Take(3).Min() + "\t" + mid + "\t" + row.Take(3).Max() + "\t" + 0 + "\t";
            //    //    timewin.Add(0);
            //    //}
            //    #endregion
            //    if (report!=String.Empty) reswriter.WriteLine(report);
            //}
            //reswriter.Close();

            #endregion

            //Console.WriteLine("Precent MinWin Delta~2 {0}",((double)minwin.Count/(minwin.Count+winwin.Count)).ToString("P"));
            Console.Write("Done.");
        }
        
        
        DataSet BetsGame = new DataSet();
        BMLines BmLinesForm = new BMLines();

        private void pars_btn_Click(object sender, EventArgs e)
        {
            if (dbName_tbox.Text != "")
            {
                dbName_tbox.Enabled = false;

                #region BetParser
                ArrayList TotalGames = new ArrayList();
                BinaryFormatter bser = new BinaryFormatter();

                #region Init DB

                DataTable Games = new DataTable("Football Games");
                DataTable BetsHistory = new DataTable("Bets History");

                DataColumn IDcol = Games.Columns.Add("Match ID", typeof(int));
                IDcol.AllowDBNull = false;
                IDcol.Unique = true;

                Games.Columns.Add("Team1", typeof(string));
                Games.Columns.Add("Team2", typeof(string));
                Games.Columns.Add("Winner", typeof(Game.WinType));
                Games.Columns.Add("Date", typeof(DateTime));
                Games.Columns.Add("Bet1", typeof(double));
                Games.Columns.Add("Bet2", typeof(double));
                Games.Columns.Add("BetDraw", typeof(double));

                DataColumn IDmatch = BetsHistory.Columns.Add("Match ID", typeof(int));
                IDcol.AllowDBNull = false;
                IDcol.Unique = false;

                BetsHistory.Columns.Add("BM name", typeof(string));
                BetsHistory.Columns.Add("48 1", typeof(double));
                BetsHistory.Columns.Add("48 2", typeof(double));
                BetsHistory.Columns.Add("48 X", typeof(double));
                BetsHistory.Columns.Add("24 1", typeof(double));
                BetsHistory.Columns.Add("24 2", typeof(double));
                BetsHistory.Columns.Add("24 X", typeof(double));
                BetsHistory.Columns.Add("12 1", typeof(double));
                BetsHistory.Columns.Add("12 2", typeof(double));
                BetsHistory.Columns.Add("12 X", typeof(double));
                BetsHistory.Columns.Add("3 1", typeof(double));
                BetsHistory.Columns.Add("3 2", typeof(double));
                BetsHistory.Columns.Add("3 X", typeof(double));
                BetsHistory.Columns.Add("30 1", typeof(double));
                BetsHistory.Columns.Add("30 2", typeof(double));
                BetsHistory.Columns.Add("30 X", typeof(double));
                BetsHistory.Columns.Add("L 1", typeof(double));
                BetsHistory.Columns.Add("L 2", typeof(double));
                BetsHistory.Columns.Add("L X", typeof(double));

                BetsGame.Tables.Add(Games);
                BetsGame.Tables.Add(BetsHistory);
                #endregion

                Random rnd = new Random();

                for (int p = 0; p < 1000; p++)
                {
                    Console.WriteLine("http://mellbet.com/archive_" + (1 + p).ToString() + ".html");

                    System.Net.WebRequest req = System.Net.WebRequest.Create("http://mellbet.com/archive_" + (1 + p).ToString() + ".html");
                    StreamReader sr = new StreamReader(req.GetResponse().GetResponseStream(), System.Text.Encoding.UTF8);
                    string html = sr.ReadToEnd().Replace("\n", "");

                    Regex teamsreg = new Regex("<td\\sclass=\"first\">\\s*<a.*?>\\s*<span>(.*?)</span>");
                    MatchCollection teams = teamsreg.Matches(html);

                    Regex datereg = new Regex("<td\\sclass=\"archive-second\">\\s*?(([\\S]+)\\s([\\S]+))\\s*?</td>");
                    MatchCollection gamedate = datereg.Matches(html);

                    Regex hiddenreg = new Regex("<tr id=\"market-(\\d+)");
                    MatchCollection hiddens = hiddenreg.Matches(html);

                    NumberFormatInfo cp = new NumberFormatInfo();
                    cp.NumberDecimalSeparator = ".";

                    for (int i = 0; i < hiddens.Count; i++)
                    {
                        DataRow gamerow = Games.NewRow();
                        Game gt = new Game { GameDate = Convert.ToDateTime(gamedate[i].Groups[1].Value), };

                        string[] vs = teams[i].Groups[1].Value.Trim().Replace("&nbsp;", " ").Split(new string[] { " v " }, StringSplitOptions.RemoveEmptyEntries);
                        for (int k = 0; k < vs.Length; k++)
                        {
                            Regex strongreg = new Regex(">(.+?)<");
                            if (strongreg.IsMatch(vs[k])) { gt.Winner = (Game.WinType)(k + 1); vs[k] = strongreg.Match(vs[k]).Groups[1].Value; }
                            switch (k)
                            {
                                case 0: gt.Team1 = vs[k]; break;
                                case 1: gt.Team2 = vs[k]; break;
                            }
                        }
                        if (gt.Winner == Game.WinType.None) gt.Winner = Game.WinType.Draw;
                        gamerow["Team1"] = gt.Team1;
                        gamerow["Team2"] = gt.Team2;
                        gamerow["Winner"] = gt.Winner;
                        gamerow["Date"] = gt.GameDate;
                        gamerow["Match ID"] = gt.ID;

                        Regex BMdatareg = new Regex("<div id=\"hidden-market-" + hiddens[i].Groups[1].Value + "\".*?(<tbody>\\s*?(<tr\\s?>.+?</tr>)+\\s*?</tbody>).*?</div>");
                        MatchCollection BMdata = BMdatareg.Matches(html);

                        Regex onelinereg = new Regex("(<tr\\s?>.+?</tr>)+\\s*?");
                        MatchCollection oneline = onelinereg.Matches(BMdata[0].Groups[1].Value);
                        BMLine[] bmls = new BMLine[oneline.Count];

                        for (int t = 0; t < oneline.Count; t++)
                        {
                            DataRow bmlinerow = BetsHistory.NewRow();

                            Regex pointsreg = new Regex(">(\\d+\\.\\d*)<");
                            MatchCollection points = pointsreg.Matches(oneline[t].Groups[1].Value);

                            Regex namereg = new Regex(">([\\w\\s]+)</");
                            double[] lt = new double[points.Count];
                            for (int r = 0; r < points.Count; r++)
                            {
                                lt[r] = Convert.ToDouble(points[r].Groups[1].Value);
                                bmlinerow[r + 2] = lt[r];
                            }
                            bmlinerow["BM name"] = namereg.Match(oneline[t].Groups[1].Value).Groups[1].Value;

                            bmlinerow["Match ID"] = gt.ID;
                            if ((string)bmlinerow["BM name"] == "Betfair")
                            {
                                gt.Bet1 = lt[lt.Length - 3];
                                gt.Bet2 = lt[lt.Length - 1];
                                gt.BetDraw = lt[lt.Length - 2];
                            }
                            BetsHistory.Rows.Add(bmlinerow);

                            bmls[t] = new BMLine(namereg.Match(oneline[t].Groups[1].Value).Groups[1].Value, lt);
                        }

                        gamerow["Bet1"] = gt.Bet1;
                        gamerow["Bet2"] = gt.Bet2;
                        gamerow["BetDraw"] = gt.BetDraw;
                        Games.Rows.Add(gamerow);

                        Console.WriteLine("{0,-30}\t{1,-30}\t{2}", gt.Team1, gt.Team2, gt.Winner);
                    }
                    BetsGame.WriteXml(dbName_tbox.Text, XmlWriteMode.WriteSchema);
                    Console.WriteLine("{1} Iteration {0} ended. Sleeping...", p, DateTime.Now.TimeOfDay);
                    Thread.Sleep(rnd.Next(5, 20) * 1000);
                    Console.WriteLine("{0} Resume...", DateTime.Now.TimeOfDay);
                }
                #endregion

                dbName_tbox.Enabled = true;
            }
            else MessageBox.Show("Name DB Missed");
        }

        private void loaddb_btn_Click(object sender, EventArgs e)
        {
            dataGridView1.DataSource = null;
            dataGridView1.Rows.Clear();
            DialogResult dr = openDB_dlg.ShowDialog();
            if (dr == System.Windows.Forms.DialogResult.OK)
            {
                BetsGame.ReadXml(openDB_dlg.OpenFile(), XmlReadMode.ReadSchema);
                dataGridView1.DataSource = BetsGame.Tables[0];
                this.Width = mainSplitContainer.Panel1.Width+dataGridView1.PreferredSize.Width;
                this.Text += " "+dataGridView1.Rows.Count;
            }

        }

        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 0)
            {
                int id = (int)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
                DataRow[] dr = BetsGame.Tables[1].Select("[Match ID] = " + id.ToString());
                if (dr.Length != 0)
                {
                    BmLinesForm.BMLtable = BetsGame.Tables[1].Clone();
                    BmLinesForm.BMLtable.Clear();
                    if (!BmLinesForm.Visible) BmLinesForm.Show();
                    
                    dr.CopyToDataTable(BmLinesForm.BMLtable, LoadOption.OverwriteChanges);
                    
                    BmLinesForm.dataGridView1.DataSource = BmLinesForm.BMLtable;
                    BmLinesForm.Size = BmLinesForm.dataGridView1.PreferredSize;
                    BmLinesForm.Text += " " + BmLinesForm.dataGridView1.Rows.Count;
                }
            }
        }

        private void export_btn_Click(object sender, EventArgs e)
        {
            if (itemToSaveCols_txt.Text != "")
            {
                DialogResult dr = export_dlg.ShowDialog();
                if (dr == System.Windows.Forms.DialogResult.OK)
                {
                    StreamWriter sw = new StreamWriter(export_dlg.FileName);
                    string row = "";
                    string[] exportCols = itemToSaveCols_txt.Text.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                    
                    foreach (string item in exportCols) row += item.Trim() + "\t"; 
                    sw.WriteLine(row);
                    row = "";
                    int strartRow=0, endRow=0;
                    string[] exportRows = itemToSaveRows_txt.Text.Split(new string[] { "-" }, StringSplitOptions.None);
                    
                    if (exportRows.Length == 0) { strartRow = 0; endRow = dataGridView1.Rows.Count; }
                    else
                    {
                        strartRow = (exportRows[0] == "") ? 0 : Convert.ToInt32(exportRows[0].Trim());
                        endRow = (exportRows[1] == "") ? dataGridView1.Rows.Count-1 : Convert.ToInt32(exportRows[1].Trim());
                    }

                    for (int i = strartRow; i < endRow; i++)
                    {
                        foreach (string item in exportCols)
                            row += dataGridView1.Rows[i].Cells[item.Trim()].Value.ToString() + "\t";

                        sw.WriteLine(row);
                        row = "";
                    }
                    sw.Close();
                }
            }
            else MessageBox.Show("Nothing to Export =(");
        }

        private void test_btn_Click(object sender, EventArgs e)
        {
            DataTable tempDT = BetsGame.Tables[0].Copy();
            DataSet tempDS = BetsGame.Copy();
            foreach ( DataRow dr in tempDT.Rows)
            {
                dr["Bet1"] = BetsGame.Tables[1].Select("[Match ID] = " + dr["Match ID"].ToString())[0]["30 1"];
                dr["Bet2"] = BetsGame.Tables[1].Select("[Match ID] = " + dr["Match ID"].ToString())[0]["30 2"];
                dr["BetDraw"] = BetsGame.Tables[1].Select("[Match ID] = " + dr["Match ID"].ToString())[0]["30 X"];
            }
            dataGridView1.DataSource = null;
            dataGridView1.Rows.Clear();
            dataGridView1.DataSource = tempDT;
            this.Text += " " + dataGridView1.Rows.Count;

            tempDS.Tables.Clear();
            tempDS.Tables.Add(tempDT);
            tempDS.Tables.Add(BetsGame.Tables[1].Copy());
            tempDS.WriteXml(openDB_dlg.FileName + "_re", XmlWriteMode.WriteSchema);
        }
    }
    
    [Serializable]
    class Game
    {
        public enum WinType { None, Team1, Team2, Draw };
        public string Team1 { get; set; }
        public string Team2 { get; set; }
        public DateTime GameDate { get; set; }
        public WinType Winner { get; set; }
        public double Bet1 { get; set; }
        public double Bet2 { get; set; }
        public double BetDraw { get; set; }
        public int ID { get { return (Team1 + Team2 + GameDate.ToString()).GetHashCode(); } }
        public BMLine[] BookMakersLine { get; set; }
    }
    [Serializable]
    class BMLine
    {
        public string Name { get; set; }
        public double[] Line = new double[18];
        public double[] Bet1 { get { return new double[] { Line[0], Line[3], Line[6], Line[9], Line[12], Line[15] }; } }
        public double[] Bet2 { get { return new double[] { Line[2], Line[5], Line[8], Line[11], Line[14], Line[17] }; } }
        public double[] BetDraw { get { return new double[] { Line[1], Line[4], Line[7], Line[10], Line[13], Line[16] }; } }
        public BMLine(string Name, double[] Line)
        {
            this.Name = Name;
            this.Line = Line;
        }
    }

}
